fix: resolve release/2.8.0 branch-review findings (car hosts, AI node IDs, discovery abort, AQ zeros)#5813
Merged
Merged
Conversation
Fixes four defects found reviewing the full release/2.8.0 branch; three would have shipped a feature broken/unsafe in production, invisible to CI. - car: HostValidator allowlist now uses Google's official "digest,packageName" entries (copied from androidx.car.app:1.9.0-alpha01's hosts_allowlist_sample). Bare package names made addAllowedHosts() throw IllegalArgumentException on the first entry, so the car app never connected to Android Auto in any release build (masked locally by the debug ALLOW_ALL_HOSTS_VALIDATOR). - ai(appfunctions): format/parse node IDs via NodeAddress.numToDefaultId/idToNum. The old Int.toString(16) emitted "!-1" instead of "!ffffffff" and the reverse toInt(16) failed for canonical 8-hex IDs > Int.MAX, so AI agents got malformed IDs and broken lookups for ~half the node-num space. Drops the dead HEX_RADIX const; adds a high-bit round-trip regression test. - discovery: pauseAndAbort() now finalizes the session, reaches the terminal state, and restores the home preset on applicationScope before cancelScanInternal() runs last. Previously it cancelled its own scanScope first, so the next suspend threw CancellationException and skipped restore/finalize — stranding the radio on the scan modem preset with the UI stuck on Failed. Mirrors stopScan()'s ordering. - node(air-quality): show present-zero readings in the summary cards (drop the != 0 guards, keep the null/presence check), consistent with the #5793 chart fix. Verified: spotlessCheck detekt assembleDebug test allTests kmpSmokeCompile -> BUILD SUCCESSFUL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rage Resolves the two MEDIUM test-coverage findings from the release/2.8.0 review. - database(fts5): the historical-message backfill was dead code. It keyed on json_extract(data, '$.text'), but DataPacket.text is a computed property that is never serialized into the stored JSON (the body is persisted as `bytes`), so the predicate was always NULL — every message received before the v39 upgrade stayed permanently unsearchable. Replace it with a Kotlin-side decode that reads each packet's payload and writes message_text via updateMessageText (previously unused). countPacketsNeedingBackfill no longer depends on json_extract. Adds PacketFtsSearchTest covering search match/non-match, conversation scoping, and the backfill regression (the new test fails against the old json_extract code). - discovery: add tests for the home-preset restoration path — a reconnect-timeout abort now reaches Complete(Failed), finalizes the session as "failed", and restores the home LoRa preset (the behavior the pauseAndAbort ordering fix enables), plus stopScan and normal-completion restore. FakeRadioController now records setLocalConfig calls so the restore can be asserted. Verified: spotlessCheck detekt assembleDebug test allTests kmpSmokeCompile -> BUILD SUCCESSFUL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jamesarich
added a commit
that referenced
this pull request
Jun 16, 2026
… IDs, discovery abort, AQ zeros) (#5813) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jamesarich
added a commit
that referenced
this pull request
Jun 16, 2026
… IDs, discovery abort, AQ zeros) (#5813) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Repairs six defects found while reviewing the full
release/2.8.0branch againstmain. Three would have shipped a feature broken or unsafe in production in a way CI cannot catch; the rest fix a silently-dead search backfill, restore suppressed clean-air telemetry, and add the regression coverage that was missing for these paths.🐛 Bug Fixes
MeshtasticCarAppService.createHostValidator()built theHostValidatorfrom acar_hosts_allowlistof bare package names, butandroidx.car.app'saddAllowedHosts()requiresdigest,packageNameentries and threwIllegalArgumentExceptionon the first one during the host handshake (masked locally by the debugALLOW_ALL_HOSTS_VALIDATOR). Replaced with Google's official entries, copied verbatim fromandroidx.car.app:1.9.0-alpha01's bundledhosts_allowlist_sample(3 Android Autogearheadkeys + 3 AAOStemplates.hostkeys).AiFunctionProviderImplused"!${node.num.toString(16)}"; for high-bit (negativeInt) node nums this produced!-1instead of the canonical!ffffffff, and the reversetoInt(16)lookup threw for canonical IDs greater thanInt.MAX. Switched to the existingNodeAddress.numToDefaultId/idToNumhelpers.pauseAndAbort()cancelled its ownscanScopebefore restoring the home LoRa preset, so the restore/finalize threwCancellationExceptionand never ran — leaving the radio on the scan modem preset with the UI stuck onFailed. Reordered to finalize and reach the terminal state, restore onapplicationScope, thencancelScanInternal()last (mirroringstopScan()).json_extract(data, '$.text'), butDataPacket.textis a computed property never serialized into the stored JSON (the body is persisted asbytes), so the backfill silently no-opped and every message received before the v39 upgrade stayed permanently unsearchable. Replaced with a Kotlin-side decode that writesmessage_textvia the previously-unusedupdateMessageText.!= 0guards on the node-detail cards (kept the?.letnull/presence check), consistent with the fix(node): chart local-node air-quality telemetry (orphaning + zero-suppression) #5793 chart/CSV zero-suppression fix.🧹 Chores
HEX_RADIXconstant fromAiFunctionProviderImpl.🧪 Testing Performed
AiFunctionProviderImplTest— addedgetNodeDetails_round_trips_high_bit_node_num(canonical ID round-trip for high-bit nums).PacketFtsSearchTest(new,core:databaseandroidHostTest) — search match/non-match, conversation scoping, and the backfill regression (the new test fails against the oldjson_extractimplementation).DiscoveryScanEngineTest(feature:discoverycommonTest) — reconnect-timeout abort reachesComplete(Failed), finalizes the session asfailed, and restores the home preset, plusstopScanand normal-completion restore.FakeRadioControllernow recordssetLocalConfigcalls so the restore can be asserted.spotlessCheck detekt assembleDebug test allTests kmpSmokeCompile→ BUILD SUCCESSFUL (includes theKoinVerificationTesttyped-bootstrap graph).🤖 Generated with Claude Code